<?php
/**
 * 
 * File manager module
 * 
 * @name			File manager
 * @description		Standard file manager module for Cosa admin
 * @version			1.0.0
 * 
 * @style			css/styles.css
 * @script			js/scripts.js
 * 
 * @author			Stijn Van Minnebruggen
 * @author_url		www.donotfold.be
 * @module_url		www.donotfold.be/projects/cosa
 * 
 */

class filemanager extends Module
{
	
	/**
	 * Holds the url location to the folder
	 * 
	 * @var		array
	 */
	
	private $_root_url;
	
	
	/**
	 * Holds the path location to the folder
	 * 
	 * @var		array
	 */
	
	private $_root_path;
	
	
	/**
	 * Holds the path to the current file
	 * 
	 * @var		string
	 */
	
	private $_file;
	
	
	/**
	 * Holds the path to the current folder
	 * 
	 * @var		string
	 */
	
	private $_folder;
	
	
	/**
	 * Holds the files & folders in the current folder (declared above)
	 * 
	 * @var		array
	 */
	
	private $_files;
	
	
	/**
	 * Holds all folders (full array)
	 * 
	 * @var		array
	 */
	
	private $_folders;
	
	
	/**
	 * Constructor function
	 * 
	 * @return	void
	 */
	
	public function __construct()
	{
		global $cosa;
		$this->_root_url = $cosa->system('site-url').$cosa->system('uploads-path');
		$this->_root_path = ROOT_PATH.'/..'.$cosa->system('uploads-path');
		$this->_checkVars();
	}
	
	
	/**
	 * Check vars on init
	 * 
	 * @return	void
	 */
	
	private function _checkVars()
	{
		global $cosa;
		if(!file_exists($this->_root_path)) $cosa->kill('Upload path not correct ('.$this->_root_path.').');
		if(empty($this->_root_url)) $cosa->kill('Uploads url not set.');
	}
	
	
	/**
	 * Get files and folders
	 * 
	 * @param	string	$path
	 * @return	array
	 */
	
	public function getFilesFolders($path='/')
	{
		// check path
			global $cosa;
			$this->_folder = $path;
			if(!is_dir($this->_root_path.$this->_folder)) $this->_folder = $this->getDirFromFile($this->_folder);
		
		// get files & folders
			$this->_files = array();
			if(!is_dir($this->_root_path.$this->_folder)) return false;
			if($h = opendir($this->_root_path.$this->_folder)) {
				while(false !== ($file = readdir($h))) {
					if($file{0} != '.') $this->_files[] = $file;
				} closedir($h);
			}
		
	}
	
	
	/**
	 * Print files and folders
	 * 
	 * @param	string	$path
	 * @return	void
	 */
	
	public function printFilesFolders($path='/')
	{
		// required
			global $cosa, $lang;
			if(!$path) $path = '/';
			$this->getFilesFolders($path);
		
		// start table
			echo '<table class="filesfolders">';
			echo '<thead><tr>';
			echo '<td width="25">&nbsp;</td>';
			echo '<td>'.$lang->get('ff_name').'</td>';
			echo '<td>'.$lang->get('ff_size').'</td>';
			echo '<td>'.$lang->get('ff_type').'</td>';
			echo '</tr></thead><tbody>'."\n";
		
		// include up
			if($path != '/') {
				
				// get upper directory
					$up_path = split('\/', $this->_folder);
					array_pop($up_path);
					$up_path = implode('/', $up_path);
					if(empty($up_path)) $up_path = '/';
				
				// print table row
					echo '<tr>';
					echo '<td><a href="'.$up_path.'" class="ff_open">'.$this->getIcon('arrow_u').'</a></td>';
					echo '<td colspan="3"><a href="'.$up_path.'" class="ff_open">..</a></td>';
					echo '</tr>'."\n";
				
			}
		
		// files & folders
			foreach($this->_files as $k => $file) {
				$type = $lang->get('ff_type_dir');
				echo '<tr>';
				$aPath = ($this->_folder == '/') ? $this->_folder.$file : $this->_folder.'/'.$file;
				if(is_dir($this->_root_path.$this->_folder.'/'.$file)) {
					echo '<td><a href="'.$aPath.'" class="ff_detail">'.$this->getIcon('folder_open').'</a></td>';
					echo '<td><a href="'.$aPath.'" class="ff_open">'.$file.'</a></td>';
					echo '<td>-</td>';
				} else {
					echo '<td><a href="'.$aPath.'" class="ff_detail">'.$this->getIcon('file').'</a></td>';
					echo '<td><a href="'.$aPath.'" class="ff_detail">'.$file.'</a></td>';
					echo '<td>'.$this->fileSize($this->_root_path.$this->_folder.'/'.$file).'</td>';
				}
				echo '<td>'.$this->fileType($this->_root_path.$this->_folder.'/'.$file).'</td>';
				echo '</tr>'."\n";
			}
		
		// close table
			echo '</tbody></table>'."\n";
		
	}
	
	
	/**
	 * Get parent dir from file or folder
	 * 
	 * @param	string	$file
	 * @return	string
	 */
	
	public function getDirFromFile($file)
	{
		// required check
			if(!file_exists($this->_root_path.$file)) return false;
		
		// fetch folders
			$folder = split('\/', $file);
			array_pop($folder);
			$folder = implode('/', $folder);
		
		// return folder
			return $folder;
		
	}
	
	
	/**
	 * Print files folders dropdown
	 * 
	 * @param	string	$select_folder
	 * @return	void
	 */
	
	public function printDropdown($select_folder=false)
	{
		if($select_folder && !is_dir($this->_root_path.$select_folder)) {
			$select_folder = $this->getDirFromFile($select_folder);
		}
		echo '<select id="folders_dd" onchange="loadPath(this.value)">'."\n";
		echo '<option value="/">/</option>'."\n";
		$this->_getDropdownOptions('/', $select_folder);
		echo '</select>'."\n";
	}
	
	
	/**
	 * Get folders (recursive function)
	 * 
	 * @param	string	$path
	 * @param	string	$select_folder
	 * @return	array
	 */
	
	private function _getDropdownOptions($path='/', $select_folder)
	{
		$fullPath = ($path == '/') ? $this->_root_path : $this->_root_path.'/'.$path;
		if(is_dir($fullPath)) {
			if($h = opendir($fullPath)) {
				while(false !== ($file = readdir($h))) {
					if($file{0} != '.' && is_dir($fullPath.'/'.$file)) {
						$newPath = ($path == '/') ? $path.$file : $path.'/'.$file;
						$selected = ($newPath == $select_folder) ? ' selected="selected"' : '';
						echo '<option value="'.$newPath.'"'.$selected.'>'.$newPath.'</option>'."\n";
						$this->_getDropdownOptions($newPath, $select_folder);
					}
				}
				closedir($h);
			}
		}
	}
	
	
	/**
	 * Get or print an icon from the kernel
	 * 
	 * @param	string	$icon
	 * @param	bool	$get
	 * @param	string	$size
	 * @return	string
	 */
	
	public function getIcon($icon, $get=true, $size='m')
	{
		// required
			global $cosa;
			$fu = $cosa->system('base-url').'/kernel/files/img/icons/'.$size.'/'.$icon.'.gif';
			$fp = ROOT_PATH.'/kernel/files/img/icons/'.$size.'/'.$icon.'.gif';
		
		// get file
			if(!file_exists($fp)) return false;
			$res = '<img src="'.$fu.'" alt="" class="icon" />';
		
		// return value
			if($get) return $res;
			else echo $res;
		
	}
	
	
	/**
	 * Get detail from path
	 * 
	 * @param	string	$file
	 * @return	void
	 */
	
	public function getDetail($file=false)
	{
		global $cosa, $lang, $m;
		if($file) {
			
			// get file vars
				$name = $this->fileName($file);
				$path = $this->_root_path.$file;
				$url = $this->_root_url.$file;
				$size = $this->fileSize($path);
				$ext = $this->fileExt($file);
				$type = $this->fileType($path, false);
				$typeF = $this->fileType($path);
				$dim = $this->imageDimensions($path);
				$rights = $this->filePermissions($path);
				$modified = $this->fileLastModified($path);
			
			// print out title
				if($type == 'dir') echo '<h1>'.$lang->get('ff_folder_detail').'</h1>'."\n";
				else echo '<h1>'.$lang->get('ff_file_detail').'</h1>'."\n";
			
			// file details
				echo '<ul class="filedetails">'."\n";
				echo '<li><label>'.$lang->get('ff_name').'</label>'.$name.'</li>'."\n";
				echo '<li><label>'.$lang->get('ff_location').'</label><a href="'.$url.'" target="_blank">'.$url.'</a></li>'."\n";
				echo '<li><label>'.$lang->get('ff_size').'</label>'.$size.'</li>'."\n";
				echo '<li><label>'.$lang->get('ff_type').'</label>'.$ext.'-'.$lang->get('ff_exttype').' ('.$typeF.')</li>'."\n";
				echo '<li><label>'.$lang->get('ff_rights').'</label>'.$rights.'</li>'."\n";
				if($dim['w']) echo '<li><label>'.$lang->get('ff_dimensions').'</label>'.$dim['w'].'x'.$dim['h'].'</li>'."\n";
				echo '<li><label>'.$lang->get('ff_modified').'</label>'.$modified.'</li>'."\n";
				echo '</ul>'."\n";
			
			// print results
				if($type == 'image') {
					$w = (!$dim['w'] || $dim['w'] > 400) ? ' width="400"' : '';
					echo '<img src="'.$this->_root_url.$file.'" alt=""'.$w.' />';
				}
			
			// buttons
				echo '<div class="buttons">';
				if($type == 'dir') {
					echo '<a href="'.$cosa->system('base-url').'/?m='.$m.'&act=edit&file='.$file.'" class="bigbtn fl-l">'.$lang->get('edit-folder').'</a>'."\n";
					echo '<a href="javascript:if(confirm(\''.$lang->get('suredelete').'\')) { window.location = \''.$cosa->system('base-url').'/?m='.$m.'&act=del&file='.$file.'\'; }" class="bigbtn fl-l">'.$lang->get('del-folder').'</a>'."\n";
				} else {
					echo '<a href="'.$cosa->system('base-url').'/?m='.$m.'&act=edit&file='.$file.'" class="bigbtn fl-l">'.$lang->get('edit-file').'</a>'."\n";
					echo '<a href="'.$cosa->system('base-url').'/?m='.$m.'&act=duplicate&file='.$file.'" class="bigbtn fl-l">'.$lang->get('dup-file').'</a>'."\n";
					if($type == 'image' && function_exists('imagecreatefromjpeg')) echo '<a href="'.$cosa->system('base-url').'/?m='.$m.'&act=resize&file='.$file.'" class="bigbtn fl-l">'.$lang->get('res-file').'</a>'."\n";
					echo '<a href="javascript:if(confirm(\''.$lang->get('suredelete').'\')) { window.location = \''.$cosa->system('base-url').'/?m='.$m.'&act=del&file='.$file.'\'; }" class="bigbtn fl-l">'.$lang->get('del-file').'</a>'."\n";
				}
				echo '</div>'."\n";
			
		} else {
			$lang->put('no-file-selected');
		}
	}
	
	
	/**
	 * Rename file or folder
	 * 
	 * @param	array	$postVars
	 * @return	bool
	 */
	
	public function editFile($postVars)
	{
		// required checks
			if(!isset($postVars['original'], $postVars['new'])) return false;
			if(!file_exists($this->_root_path.$postVars['original'])) return false;
		
		// rename file or folder
			return rename($this->_root_path.$postVars['original'], $this->_root_path.$postVars['new']);
		
	}
	
	
	/**
	 * Add file or folder
	 * 
	 * @param	array	$postVars
	 * @return	bool
	 */
	
	public function addFile($postVars)
	{
		return true;
	}
	
	
	/**
	 * Get filename from file
	 * 
	 * @param	string	$file
	 * @return	string
	 */
	
	public function fileName($file)
	{
		$name = split('\/', $file);
		$name = array_reverse($name);
		$name = $name[0];
		return $name;
	}
	
	
	/**
	 * Get filesize from file (from php.net)
	 * 
	 * @param	string	$file
	 * @return	string
	 */
	
	public function fileSize($file)
	{
		// required
			if(!file_exists($file)) return false;
			$bytes = filesize($file);
		
		// security check
			if($bytes <= 0) return '0 Byte';
		
		// get value
			$convention = 1000; // [1000->10^x|1024->2^x]
			$s = array('B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB');
			$e = floor(log($bytes,$convention));
			return round($bytes/pow($convention,$e),2).' '.$s[$e];
		
	}
	
	
	/**
	 * Get file type
	 * 
	 * @param	string	$file
	 * @return	string
	 */
	
	public function fileType($file, $getLang=true)
	{
		// required
			global $lang;
			if(!file_exists($file)) return false;
			$is_dir = is_dir($file);
			if($is_dir) return ($getLang) ? $lang->get('ff_type_dir') : 'dir';
			$ext = $this->fileExt($file);
		
		// types
			$types = array(	'image'		=> array('jpg', 'jpeg', 'gif', 'png', 'bmp')
							,'flash'	=> array('swf', 'fla')
							,'doc'		=> array('pdf', 'doc', 'docx', 'docm', 'wps', 'dot', 'rtf', 'txt')
							,'sheet'	=> array('xls', 'xml', 'xlt', 'xlw', 'wk1', 'wk3', 'wks', 'dbf', 'prn', 'csv', 'xlsx', 'xlsb', 'xlmb')
							,'video'	=> array('wmv', 'flv', 'avi', 'mov', 'mpeg', 'mpg')
							,'audio'	=> array('wma', 'mp3', 'wav', 'mid', 'midi', 'asf', 'aiff', 'au')
							,'archive'	=> array('zip', 'rar')
							);
		
		// fetch filetype
			$fileType = $ext.'-'.$lang->get('ff_exttype');
			foreach($types as $type => $typeExts) {
				if(in_array($ext, $typeExts)) $fileType = $type;
			}
		
		// return value
			if($getLang) $ret = $lang->get('ff_type_'.$fileType);
		
		// return var
			return ($ret) ? $ret : $fileType;
		
	}
	
	
	/**
	 * Get file extension
	 * 
	 * @param	string	$file
	 * @return	string
	 */
	
	public function fileExt($file)
	{
		// required
			if(empty($file)) return false;
		
		// get ext
			$ext = split('\.', $file);
			$ext = array_reverse($ext);
			$ext = isset($ext[0]) ? $ext[0] : false;
		
		// get type
			return $ext;
		
	}
	
	
	/**
	 * Get file permissions
	 * 
	 * @param	string	$file
	 * @return	string
	 */
	
	public function filePermissions($file)
	{
		// get permissions
			if(!file_exists($file)) return false;
			$perms = fileperms($file);
		
		// set permissions
			if (($perms & 0xC000) == 0xC000)		$info = 's';	# Socket
			elseif (($perms & 0xA000) == 0xA000)	$info = 'l';	# Symbolic Link
			elseif (($perms & 0x8000) == 0x8000)	$info = '-';	# Regular
			elseif (($perms & 0x6000) == 0x6000)	$info = 'b';	# Block special
			elseif (($perms & 0x4000) == 0x4000)	$info = 'd';	# Directory
			elseif (($perms & 0x2000) == 0x2000)	$info = 'c';	# Character special
			elseif (($perms & 0x1000) == 0x1000)	$info = 'p';	# FIFO pipe
			else									$info = 'u';	# Unknown
		
		// owner
			$info .= (($perms & 0x0100) ? 'r' : '-');
			$info .= (($perms & 0x0080) ? 'w' : '-');
			$info .= (($perms & 0x0040) ?
			(($perms & 0x0800) ? 's' : 'x' ) :
			(($perms & 0x0800) ? 'S' : '-'));
		
		// group
			$info .= (($perms & 0x0020) ? 'r' : '-');
			$info .= (($perms & 0x0010) ? 'w' : '-');
			$info .= (($perms & 0x0008) ?
			(($perms & 0x0400) ? 's' : 'x' ) :
			(($perms & 0x0400) ? 'S' : '-'));
		
		// world
			$info .= (($perms & 0x0004) ? 'r' : '-');
			$info .= (($perms & 0x0002) ? 'w' : '-');
			$info .= (($perms & 0x0001) ?
			(($perms & 0x0200) ? 't' : 'x' ) :
			(($perms & 0x0200) ? 'T' : '-'));
		
		//return info
			return $info;
		
	}
	
	
	/**
	 * Get the file modification time
	 * 
	 * @param	string	$file
	 * @param	string	$format
	 * @return	string
	 */
	
	public function fileLastModified($file, $format=false)
	{
		// required
			global $cosa;
			if(!file_exists($file)) return false;
		
		// get time
			$time = filemtime($file);
		
		// format
			$f = (!empty($format)) ? $format : $cosa->system('datetime');
			$m = date($f, $time);
		
		// return value
			return $m;
		
	}
	
	
	/**
	 * Get image dimensions
	 * 
	 * @param	string	$file
	 * @return	array
	 */
	
	public function imageDimensions($file)
	{
		// get file ext
			if(!file_exists($file)) return false;
			$ext = $this->fileExt($file);
		
		// create image from ext
			if($ext == 'jpg' || $ext == 'jpeg') $im = (function_exists('imagecreatefromjpeg')) ? imagecreatefromjpeg($file) : false;
			else if($ext == 'gif') $im = (function_exists('imagecreatefromgif')) ? imagecreatefromgif($file) : false;
			else if($ext == 'png') $im = (function_exists('imagecreatefrompng')) ? imagecreatefrompng($file) : false;
			else $im = false;
		
		// get file dimensions
			$h = ($im) ? imagesy($im) : false;
			$w = ($im) ? imagesx($im) : false;
			$dim = array('h' => $h, 'w' => $w);
		
		// return dim
			return $dim;
		
	}
	
	
	/**
	 * Get root path
	 * 
	 * @return	string
	 */
	
	public function root_path()
	{
		return $this->_root_path;
	}
	
	
	/**
	 * Get root url
	 * 
	 * @return	string
	 */
	
	public function root_url()
	{
		return $this->_root_url;
	}
	
	

}

?>